package com.service.impl;

import com.DTO.FriendDTO;
import com.WebSocket.FriendDelete;
import com.WebSocket.SocketData;
import com.WebSocket.WebSocket;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.entity.ChatRecord;
import com.entity.Friend;
import com.entity.User;
import com.mapper.ChatRecordMapper;
import com.mapper.FriendMapper;
import com.mapper.UserMapper;
import com.service.FriendService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author XTC
 * @since 2024-07-10
 */
@Service
public class FriendServiceImpl extends ServiceImpl<FriendMapper, Friend> implements FriendService {
    @Autowired
    private FriendMapper friendMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private ChatRecordMapper chatRecordMapper;

    @Override
    public Set<User> getAllFriendOf(Integer userId) {
        QueryWrapper<Friend> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id1", userId)
                .or().eq("user_id2", userId);
        List<Friend> friends = friendMapper.selectList(queryWrapper);
        Set<User> userSet = new HashSet<>();
        for(Friend friend : friends) {
            User user = null;
            QueryWrapper<User> wrapper = new QueryWrapper<>();
            if(friend.getUserId1().equals(userId)) {
                wrapper.eq("id", friend.getUserId2());
            }else {
                wrapper.eq("id", friend.getUserId1());
            }
            user = this.userMapper.selectOne(wrapper);
            userSet.add(user);
        }
        userSet.add(this.userMapper.selectById(userId));
        return userSet;
    }

    @Override
    public List<Integer> getAllFriendIdOf(Integer userId) {
        List<Integer> idList = new ArrayList<>();
        QueryWrapper<Friend> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id1", userId)
                .or().eq("user_id2", userId);
        List<Friend> friends = friendMapper.selectList(queryWrapper);
        for(Friend friend : friends) {
            if(friend.getUserId1().equals(userId)) {
                idList.add(friend.getUserId2());
            }else {
                idList.add(friend.getUserId1());
            }
        }
        idList.add(userId);
        return idList;
    }

    @Override
    public boolean deleteFriend(Integer userId1, Integer userId2) {
        QueryWrapper<ChatRecord>chatRecordQueryWrapper = new QueryWrapper<>();
        chatRecordQueryWrapper.eq("send_user_id", userId1).eq("receive_user_id", userId2)
                .or(w -> {
                    w.eq("send_user_id", userId2).eq("receive_user_id", userId1);
                });
        this.chatRecordMapper.delete(chatRecordQueryWrapper);
        QueryWrapper<Friend> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id1", userId1).eq("user_id2", userId2)
                .or(w -> {
                    w.eq("user_id1", userId2).eq("user_id2", userId1);
                });
        this.friendMapper.delete(queryWrapper);
        this.sendFriendDelete(userId1, userId2);
        return true;
    }

    private void sendFriendDelete(Integer userId1, Integer userId2) {
        User user = this.userMapper.selectById(userId1);
        FriendDelete friendDelete = new FriendDelete();
        friendDelete.setUserId(userId1);
        friendDelete.setUserName(user.getName());
        SocketData socketData = new SocketData();
        socketData.setFriendDelete(friendDelete);
        socketData.setType("friend_delete");
        WebSocket.sendOneMessage(String.valueOf(userId2), socketData);
    }

    @Override
    public List<User> getFriendByName(Integer userId, String name) {
        List<Integer> friendIdList = this.getAllFriendIdOf(userId);
        if(friendIdList.isEmpty()) {
            return new ArrayList<>();
        }
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.in("id", friendIdList)
                .like("name", name);
        return this.userMapper.selectList(wrapper);
    }

    @Override
    public boolean isFriend(Integer userId1, Integer userId2) {
        QueryWrapper<Friend> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id1", userId1)
                .eq("user_id2", userId2)
                .or(w -> {
                    w.eq("user_id1", userId2)
                            .eq("user_id2", userId1);
                });
        return this.friendMapper.selectOne(queryWrapper) != null;
    }
}
